package com.kws.merchant.service.impl;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.kws.common.core.domain.R;
import com.kws.common.core.exception.ServiceException;
import com.kws.common.core.utils.uuid.UUID;
import com.kws.common.security.auth.AuthUtil;
import com.kws.merchant.domain.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kws.merchant.domain.po.ContractPo;
import com.kws.merchant.domain.po.CreateContractPo;
import com.kws.merchant.domain.po.SignLinkPo;
import com.kws.merchant.service.*;
import com.kws.system.api.RemoteUserService;
import com.kws.system.api.domain.*;
import com.kws.merchant.mapper.ContractMapper;
import com.kws.system.api.RemoteToolService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 合同管理-合同(Contract)表服务实现类
 *
 * @author yxy
 * @since 2024-10-29 15:37:31
 */
@Service("contractService")
public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> implements ContractService {

    @Resource
    private ContractMapper contractMapper;
    @Autowired
    private ContractTemplateService contractTemplateService;
    @Autowired
    private ContractReplenishService contractReplenishService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private RemoteToolService remoteToolService;
    @Autowired
    private MerchantService merchantService;
    @Autowired
    private RemoteUserService remoteUserService;


    /**
     * 分页查询列表
     */
    @Override
    public Page<Contract> pageList(ContractPo contractPo) {
       /* Integer listType = contractPo.getListType();
        SignFlowRq signFlowRq = new SignFlowRq();
//        remoteToolService.signFlowList();
        ArrayList<Integer> signFlowStatus = new ArrayList<>();
        if (listType==0){
            //列表类型0合同列表 1合同归档
            signFlowStatus.add(1);
            signFlowStatus.add(3);
            signFlowStatus.add(5);
            signFlowStatus.add(7);
        }else{
            signFlowStatus.add(2);
        }
        Integer userType = contractPo.getUserType();
        SysUser sysUser = AuthUtil.getLoginUser().getSysUser();
        Operator operator = new Operator();
        Calendar calendar = Calendar.getInstance();
        Date nowTime = calendar.getTime();
        calendar.add(Calendar.YEAR,-5);
        Date agoTime = calendar.getTime();
        switch (userType){
            case 0:
                Long companyId = sysUser.getCompanyId();
                Merchant merchant = merchantService.getById(companyId);
                if (ObjectUtils.isEmpty(merchant)){
                    throw new RuntimeException("没有查询到该商家信息");
                }
                operator.setPsnAccount(merchant.getContactInformation());
                break;
            case 1:
                operator.setPsnAccount(sysUser.getPhonenumber());
                break;
        }
        signFlowRq.setPageNum(contractPo.getPageSize());
        signFlowRq.setPageSize(contractPo.getTotalPage());
        signFlowRq.setOperator(operator);
        signFlowRq.setSignFlowStatus(signFlowStatus);
        signFlowRq.setSignFlowStartTimeFrom(agoTime.getTime());
        signFlowRq.setSignFlowStartTimeTo(nowTime.getTime());
        R<ResultDto> resultDtoR = remoteToolService.signFlowList(signFlowRq);
        if (ObjectUtils.isEmpty(resultDtoR)){
            throw new RuntimeException(resultDtoR.getMsg());
        }
        JSONObject dataJson = JSONObject.parseObject(JSONObject.toJSONString(resultDtoR.getData().getData()), JSONObject.class);
        List<JSONObject> list = dataJson.getJSONArray("signFlowInfos").toJavaList(JSONObject.class);
        String signFlowId = list.stream().map(x -> x.get("signFlowId").toString()).collect(Collectors.joining(","));

*/

        Page<Contract> page = new Page<>(contractPo.getPageSize(), contractPo.getTotalPage());
        LambdaQueryWrapper<Contract> queryWrapper = Wrappers.lambdaQuery();
        String contractNo = contractPo.getContractNo();//合同编号
        String contractName = contractPo.getContractName();//合同名称
        String contractType = contractPo.getContractType();//合同类型
        String secondParty = contractPo.getSecondParty();//乙方-客户名称
        Integer type = contractPo.getType();//列表类型0合同列表 1合同归档
        SysUser sysUser = AuthUtil.getLoginUser().getSysUser();
        boolean flag = sysUser.isAdmin();//判断是否为管理员，管理员可查看所有数据
        Long companyId = sysUser.getCompanyId();
        if (StringUtils.isNotEmpty(contractNo)) {
            queryWrapper.eq(Contract::getContractNo, contractNo);
        }
        if (StringUtils.isNotEmpty(contractName)) {
            queryWrapper.eq(Contract::getContractName, contractName);
        }
        if (StringUtils.isNotEmpty(contractType)) {
            queryWrapper.eq(Contract::getContractType, contractType);
        }
        if (StringUtils.isNotEmpty(secondParty)) {
            queryWrapper.eq(Contract::getSecondParty, secondParty);
        }
        if (!flag) {
            if (companyId == null) {
                throw new RuntimeException("用户");
            }
            if (companyId != null) {
                queryWrapper.eq(Contract::getMerchantId, companyId);
            }
        }

        if (type!=null) {
            switch (type) {
                case 0:
                    queryWrapper.ne(Contract::getStatus, 2);
                    break;
                case 1:
                    queryWrapper.eq(Contract::getStatus, 2);
                    break;
            }
        }

        return this.page(page, queryWrapper);
    }

    /**
     * 新增合同
     *
     * @param contract
     * @return
     */
    @Override
    public boolean addContract(Contract contract) {
        contract.setContractNo("HT" + UUID.randomUUID());
        contract.setStatus(2);
        return this.save(contract);
    }

    /**
     * 合同详情
     *
     * @param id
     * @return
     */
    @Override
    public Contract detailById(Long id) {
        Contract contract = this.getById(id);
        if (ObjectUtils.isEmpty(contract)) {
            throw new RuntimeException("没有该合同信息");
        }
        //查询补充协议
        if (StringUtils.isNotEmpty(contract.getReplenishNo())) {
            ContractReplenish contractReplenish = contractReplenishService.getReplenishNo(contract.getReplenishNo());
            if (ObjectUtils.isNotEmpty(contractReplenish)){
//                contract.setContractReplenish(contractReplenish);
            }
        }
        //查询合同模板
//        ContractTemplate contractTemplate = contractTemplateService.getById(contract.getId());
//        contract.setContractTemplate(contractTemplate.getFile());
//        contract.setContent(contractTemplate.getContent());
        return contract;
    }

    /**
     * 创建合同--前端无需调用创建合同接口，生成订单时自动调用
     * @param createContractPo
     * @return
     */
    @Override
    public Object createContract(CreateContractPo createContractPo) {
        Long orderId = createContractPo.getOrderId();
        Integer projectType = createContractPo.getProjectType();
        //查询合同模板是否上传
        ContractTemplate contractTemplate=contractTemplateService.getType(projectType);
        if (ObjectUtils.isEmpty(contractTemplate)){
            throw new RuntimeException("请先上传合同模板");
        }
        String docTemplateId = contractTemplate.getTemplateId();
        Order order = orderService.getById(orderId);
        if (ObjectUtils.isEmpty(order)){
            throw new RuntimeException("订单不能为空！");
        }
        //获取订单价格-用于填充到文件中，后续发起签署流程
        BigDecimal orderPrice = order.getOrderPrice();
        //查询模板控件
        R<ResultDto> componentsInfo = remoteToolService.getComponentsInfo(docTemplateId);
        if (R.FAIL == componentsInfo.getCode())
        {
            throw new ServiceException(componentsInfo.getMsg());
        }
        ResultDto data = componentsInfo.getData();
        if (data.getCode()!=0){
            throw new RuntimeException("查询模板控件失败");
        }
        /**
         * "docTemplateId": "",
         * 		"docTemplateName": "",
         * 		"fileDownloadUrl": "",
         * 		"components": null
         */
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(data.getData()), JSONObject.class);
        JSONArray components = jsonObject.getJSONArray("components");
        if (components==null){
            throw new RuntimeException("请先添加模板控件，用于自动填充价格和签约单位！！");
        }


        AtomicBoolean priceFlag = new AtomicBoolean(false);
        ArrayList<Component> list = new ArrayList<>();
        //商家签章
        ArrayList<FieldPositionPo> merchantFieldPosition = new ArrayList<>();
        //用户签章
        ArrayList<FieldPositionPo> userFieldPosition = new ArrayList<>();
        components.forEach(x->{
            JSONObject component = JSONObject.parseObject(JSONObject.toJSONString(x), JSONObject.class);
            String componentKey = component.getOrDefault("componentKey", "").toString();
            if ("price".equals(componentKey)){
                priceFlag.set(true);
                String componentId = component.getOrDefault("componentId", "").toString();
                Component componentEntity = new Component();
                componentEntity.setComponentId(componentId);
                componentEntity.setComponentValue(orderPrice.toString());
                list.add(componentEntity);
            }
            JSONObject componentPosition=null;
            FieldPositionPo fieldPositionPo = new FieldPositionPo();
            //商家签章
            if ("sign1".equals(componentKey)){
                componentPosition = JSONObject.parseObject(JSONObject.toJSONString(component.get("componentPosition")), JSONObject.class);
                if (componentPosition!=null){
                    String componentPositionX = componentPosition.getOrDefault("componentPositionX", "0").toString();
                    String componentPositionY = componentPosition.getOrDefault("componentPositionY", "0").toString();
                    String componentPageNum = componentPosition.getOrDefault("componentPageRange", "0").toString();
                    fieldPositionPo.setPositionX(Double.valueOf(componentPositionX));
                    fieldPositionPo.setPositionY(Double.valueOf(componentPositionY));
                    fieldPositionPo.setPositionPage(componentPageNum);
                    merchantFieldPosition.add(fieldPositionPo);
                }
            }
            //用户签章
            if ("sign2".equals(componentKey)){
                componentPosition = JSONObject.parseObject(JSONObject.toJSONString(component.get("componentPosition")), JSONObject.class);
                if (componentPosition!=null){
                    String componentPositionX = componentPosition.getOrDefault("componentPositionX", "0").toString();
                    String componentPositionY = componentPosition.getOrDefault("componentPositionY", "0").toString();
                    String componentPageNum = componentPosition.getOrDefault("componentPageRange", "0").toString();
                    fieldPositionPo.setPositionX(Double.valueOf(componentPositionX));
                    fieldPositionPo.setPositionY(Double.valueOf(componentPositionY));
                    fieldPositionPo.setPositionPage(componentPageNum);
                    userFieldPosition.add(fieldPositionPo);
                }
            }
        });
        if (userFieldPosition.size()==0){
            throw new RuntimeException("用户控件为空");
        }
        if (!priceFlag.get()){
            throw new RuntimeException("没有价格控件,请联系平台方添加");
        }
        //模板文件名称
        String fileName=jsonObject.getOrDefault("docTemplateName", "").toString();

        CreateTemplate createTemplate = new CreateTemplate();
        createTemplate.setDocTemplateId(docTemplateId);
        createTemplate.setFileName(fileName);
        createTemplate.setComponents(list);

        //填充合同金额
        R<ResultDto> byDocTemplate = remoteToolService.createByDocTemplate(createTemplate);
        if (R.FAIL == byDocTemplate.getCode())
        {
            throw new ServiceException(byDocTemplate.getMsg());
        }
        ResultDto byDocTemplateData = byDocTemplate.getData();
        if (byDocTemplateData.getCode()!=0){
            throw new RuntimeException(byDocTemplateData.getMessage());
        }
        JSONObject byDocTemplateJsonObj = JSONObject.parseObject(JSONObject.toJSONString(byDocTemplateData.getData()), JSONObject.class);
        String fileId = byDocTemplateJsonObj.getOrDefault("fileId", "").toString();
        /**
         * {"code":0,"message":"成功","data":{"fileId":"b8fd986bd86542ddabf04b5902efad47",
         * "fileDownloadUrl":""}}
         */
        if (StringUtils.isEmpty(fileId)){
            throw new RuntimeException("填充文件失败");
        }

        Long merchantId = order.getMerchantId();
        if (merchantId==null){
            throw new RuntimeException("订单中商家不能为空");
        }
        Long userId = order.getUserId();
        if (userId==null){
            throw new RuntimeException("订单中用户不能为空");
        }
        Merchant merchant = merchantService.getById(merchantId);
        if (ObjectUtils.isEmpty(merchant)){
            throw new RuntimeException("没有该商家信息");
        }
        R<SysUser> sysUserR = remoteUserService.getUserById(userId);
        if (R.FAIL == sysUserR.getCode())
        {
            throw new ServiceException(sysUserR.getMsg());
        }
        SysUser sysUser = sysUserR.getData();
        String contractName = order.getOrderNo() + "订单合同";
        //创建合同
        CreateContractDto createContractDto = new CreateContractDto();
        createContractDto.setFileId(fileId);
        createContractDto.setFileName(fileName);
        createContractDto.setSignFlowTitle(contractName);
        createContractDto.setMerchantName(merchant.getCompanyName());//公司名称
        createContractDto.setMerchantCode(merchant.getCompanyCode());//公司组织代码
        createContractDto.setMerchantUserPhone(merchant.getContactInformation());//经办人号码
        createContractDto.setMerchantUserName(merchant.getContactPerson());//经办人名称
        createContractDto.setMerchantUserIdCard(merchant.getDocumentNumber());//经办人身份证号码

        createContractDto.setUserName(sysUser.getNickName());
        createContractDto.setUserPhone(sysUser.getPhonenumber());
        createContractDto.setMerchantFieldPosition(merchantFieldPosition);//商家签章
        createContractDto.setUserFieldPosition(userFieldPosition);//用户签章
        //创建合同并发起
        R<ResultDto> contractResult = remoteToolService.createContract(createContractDto);
        if (R.FAIL == contractResult.getCode())
        {
            throw new ServiceException(contractResult.getMsg());
        }
        JSONObject contractResultJsonObj = JSONObject.parseObject(JSONObject.toJSONString(contractResult.getData().getData()), JSONObject.class);
        Contract contract = new Contract();
        contract.setContractType(projectType);//合同类型
        contract.setContractNo(UUID.randomUUID().toString());
        contract.setOrderId(orderId);//订单编号
        contract.setItemNo("");//项目编号
        contract.setSignSequence(0);//签署顺序
        contract.setStartTime(new Date());//开始时间
        contract.setContractName(contractName);//合同名称
        contract.setFirstParty(merchant.getCompanyName());//甲方
        contract.setSecondParty(sysUser.getNickName());//乙方
        contract.setContractMoney(orderPrice);//合同金额
        contract.setMerchantId(merchantId);//商家id
        contract.setUserId(userId);
        contract.setEnable("1");
        contract.setStatus(1);
        contract.setSignFlowId(contractResultJsonObj.getString("signFlowId"));
//        createContract1(fileName, fileId);
        return this.save(contract);
    }


    private void createContract1(String fileName, String fileId) {
        HashMap<String, Object> param = new HashMap<>();

        HashMap<String, Object> docs = new HashMap<>();
        ArrayList<HashMap<String, String>> docList = new ArrayList<>();
        HashMap<String, String> doc = new HashMap<>();
        doc.put("fileId", fileId);
        doc.put("fileName", fileName);
        docList.add(doc);
        docs.put("docs",docList);
        param.put("docs",docs);

        HashMap<String, Object> signFlowConfig = new HashMap<>();
        signFlowConfig.put("signFlowTitle","测试签署合同");
        param.put("signFlowConfig",signFlowConfig);

        HashMap<String, Object> signer = new HashMap<>();
        signer.put("signerType",1);

        HashMap<String, Object> noticeConfig = new HashMap<>();
        noticeConfig.put("noticeTypes",1);
        signer.put("noticeConfig",noticeConfig);

        //企业用户信息
        HashMap<String, Object> orgSignerInfo = new HashMap<>();
        orgSignerInfo.put("orgName","公司名称");//企业/机构名称（账号标识）
        HashMap<String, Object> orgInfo = new HashMap<>();
        orgInfo.put("legalRepIDCardNum","");//企业/机构证件号
        orgInfo.put("orgIDCardType","");//企业/机构证件类型，可选值如下：CRED_ORG_USCC - 统一社会信用代码 CRED_ORG_REGCODE - 工商注册号
        orgSignerInfo.put("orgInfo",orgInfo);
        HashMap<String, Object> transactorInfo = new HashMap<>();
        transactorInfo.put("psnAccount","");//经办人账号标识，手机号或邮箱
        HashMap<String, Object> psnInfo = new HashMap<>();
        psnInfo.put("psnName","");//经办人姓名
        psnInfo.put("psnIDCardNum","");//经办人证件号
        /**
         * 经办人证件类型，可选值如下：
         * CRED_PSN_CH_IDCARD - 中国大陆居民身份证（默认值）
         * CRED_PSN_CH_HONGKONG - 香港来往大陆通行证（回乡证）
         * CRED_PSN_CH_MACAO - 澳门来往大陆通行证（回乡证）
         * CRED_PSN_CH_TWCARD - 台湾来往大陆通行证（台胞证）
         * CRED_PSN_PASSPORT - 护照
         * 【注】CRED_PSN_CH_IDCARD 类型同时兼容港澳台居住证（81、82、83开头18位证件号）、外国人永久居住证（9开头18位证件号）
         */
        psnInfo.put("psnIDCardType","");
        transactorInfo.put("psnInfo",psnInfo);
        orgSignerInfo.put("transactorInfo",transactorInfo);

        HashMap<String, Object> signFields = new HashMap<>();
        HashMap<String, Object> signField = new HashMap<>();
        signField.put("fileId", fileId);
        HashMap<String, Object> normalSignFieldConfig = new HashMap<>();
        /**
         * true - 是，false - 否
         * 补充说明：
         * 自由签章 指不限制印章、签署位置、签章样式（单页、骑缝）、和签章个数。
         * 自由签章模式下，无需传normalSignFieldConfig对象下的其他参数。
         */
        normalSignFieldConfig.put("freeMode","");//是否自由签章，默认值 false
        /**
         * 是否后台自动落章，默认值 false
         * true - 后台自动落章（无感知），false - 签署页手动签章
         * 补充说明：
         * 当签署方为个人时，不支持自动签章。
         * 当签署方为机构（且非应用Id所属企业），静默签署自动落章需先经过印章授权，点击查看印章授权规则。
         * 当签署方为应用Id所属主体企业自身静默签署时，支持后台自动落章。
         */
        normalSignFieldConfig.put("autoSign","");
        normalSignFieldConfig.put("movableSignField","");
        normalSignFieldConfig.put("psnSealStyles","");
        normalSignFieldConfig.put("signFieldSize","");
        normalSignFieldConfig.put("signFieldStyle","");
        HashMap<String, Object> signFieldPosition = new HashMap<>();
        signFieldPosition.put("positionPage","");
        signFieldPosition.put("positionX","");
        signFieldPosition.put("positionY","");
        normalSignFieldConfig.put("signFieldPosition",signFieldPosition);
        signFields.put("signField",normalSignFieldConfig);
        signFields.put("signFiels",signField);
    }

    /**
     * 获取签署链接
     * @return
     */
    @Override
    public Object signLink(SignLinkPo signLinkPo) {
        Long contractId = signLinkPo.getContractId();
        Integer type = signLinkPo.getType();//类型0商家 1用户
        Contract contract = this.getById(contractId);
        QuerySignUrlRq querySignUrlRq = new QuerySignUrlRq();
        querySignUrlRq.setSignFlowId(contract.getSignFlowId());
        querySignUrlRq.setClientType("ALL");//指定客户端类型
        querySignUrlRq.setNeedLogin(true);//是否需要登录打开链接（默认值 false）true - 需登录打开链接，false - 免登录
        querySignUrlRq.setUrlType(2);//链接类型（默认值 2）1 - 预览链接（仅限查看，不能签署）， 2 - 签署链接
        OperatorRq operatorRq = new OperatorRq();
        switch (type){
            case 0:
                Merchant merchant = merchantService.getById(contract.getMerchantId());
                /*OrganizationRq organizationRq = new OrganizationRq();
                organizationRq.setOrgName(merchant.getCompanyName());
                querySignUrlRq.setOrganization(organizationRq);*/
//                operatorRq.setPsnAccount(sysUser.getPhonenumber());
                operatorRq.setPsnAccount(merchant.getContactInformation());
                querySignUrlRq.setOperator(operatorRq);
                break;
            case 1:
                R<SysUser> resultDtoR = remoteUserService.getUserById(contract.getUserId());
                if (R.FAIL == resultDtoR.getCode())
                {
                    throw new ServiceException(resultDtoR.getMsg());
                }
                SysUser sysUser = resultDtoR.getData();
                operatorRq.setPsnAccount(sysUser.getPhonenumber());
                querySignUrlRq.setOperator(operatorRq);
                break;
        }
        R<ResultDto> resultDtoR = remoteToolService.signLink(querySignUrlRq);
        if (R.FAIL == resultDtoR.getCode())
        {
            throw new ServiceException(resultDtoR.getMsg());
        }
        Object data = resultDtoR.getData().getData();
        return data;
    }

    /**
     * 下载已签署文件--未签署完成的文件不可下载
     * @param signFlowId
     * @return
     */
    @Override
    public String fileDownloadUrl(String signFlowId) {
        R<ResultDto> resultDtoR = remoteToolService.fileDownloadUrl(signFlowId);
        if (R.FAIL == resultDtoR.getCode())
        {
            throw new ServiceException(resultDtoR.getMsg());
        }
        Object data = resultDtoR.getData().getData();
        JSONObject contractResultJsonObj = JSONObject.parseObject(JSONObject.toJSONString(data), JSONObject.class);
        JSONArray files = contractResultJsonObj.getJSONArray("files");
        Object file0 = files.get(0);
        JSONObject fileJson = JSONObject.parseObject(JSONObject.toJSONString(file0), JSONObject.class);
        String downloadUrl = fileJson.getOrDefault("downloadUrl", "").toString();
        return downloadUrl;
    }

    /**
     * 查看合同--免登录，任何人可查看
     * @param signFlowId
     * @return
     */
    @Override
    public String signViewLink(String signFlowId) {
        R<ResultDto> resultDtoR = remoteToolService.signViewLink(signFlowId);
        if (R.FAIL == resultDtoR.getCode())
        {
            throw new ServiceException(resultDtoR.getMsg());
        }
        Object data = resultDtoR.getData().getData();
        JSONObject contractResultJsonObj = JSONObject.parseObject(JSONObject.toJSONString(data), JSONObject.class);
        String url = contractResultJsonObj.getOrDefault("url", "").toString();
        return url;
    }

    /**
     * 回调通知
     * @param json
     * @return
     */
    @Override
    public Boolean callBackUrl(JSONObject json) {
        System.out.println("回调成功"+json);
        //流程结束时把
        String action = json.getOrDefault("action", "").toString();
        //当回调通知时，流程结束时赋予合同状态
        boolean flag=false;
        if ("SIGN_FLOW_COMPLETE".equals(action)){
            String signFlowId = json.getOrDefault("signFlowId", "").toString();
            String signFlowStatus = json.getOrDefault("signFlowStatus", "").toString();
            Contract contract = this.getBySignFlowId(signFlowId);
            if (ObjectUtils.isEmpty(contract)){
                throw new RuntimeException("没有该合同："+signFlowId);
            }
            contract.setStatus(Integer.valueOf(signFlowStatus));
            flag=this.updateById(contract);
        }
        return flag;
    }

    /**
     * 撤销签署流程
     * @param signFlowRevoke
     * @return
     */
    @Override
    public Boolean signFlowRevoke(SignFlowRevoke signFlowRevoke) {
        R<ResultDto> resultDtoR = remoteToolService.signFlowRevoke(signFlowRevoke);
        if (R.FAIL == resultDtoR.getCode())
        {
            throw new ServiceException(resultDtoR.getMsg());
        }
        int code = resultDtoR.getData().getCode();
        if (code==0){
            return true;
        }else{
            return false;
        }
    }

    private Contract getBySignFlowId(String signFlowId) {
        return this.getOne(Wrappers.<Contract>lambdaQuery().eq(Contract::getSignFlowId,signFlowId));
    }
}
